/*
 * Copyright 2016-2019 yoara
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package yhao.infra.apilist;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;

import static yhao.infra.apilist.JsonCommonCodeEnum.E0001;
import static yhao.infra.apilist.JsonCommonCodeEnum.E0020;

/**
 * 微服务层继承的RestfulBaseController
 * <p>微服务层不做单独的对外服务项目时，继承RestfulBaseController
 * 主要是做了对异常封装成{@link RequestResult}的处理
 *
 * @author yoara
 */
public class RestfulBaseController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 指定请求异常处理
     */
    @ExceptionHandler({RequestResultException.class})
    public RequestResult requestResultException(RequestResultException e) {
        logger.error("请求错误信息:" + e.getMessage(), e);
        RequestResult rr = new RequestResult(false,null,e.getMessage());
        rr.setMsgBody(e.getMsgBody());
        if(e.getCodeEnum()!=null){
            rr.setErrCode(e.getCodeEnum().getStatus());
        }else{
            rr.setErrCode(e.getCode());
        }
        return rr;
    }

    /**
     * 全局的异常处理
     */
    @ExceptionHandler({Exception.class})
    public RequestResult exception(Exception e) {
        logger.error("api 错误信息:" + e.getMessage(), e);
        String msg = e.getMessage();
        String code = null;
        if(StringUtils.isEmpty(msg)){
            msg = "空参数，请检查";
        }else if(msg.contains("DuplicateKeyException")){
            msg = "存在重复的参数与已有数据冲突，请修改";
            code = E0020.getStatus();
        }else if(msg.contains("BadSqlGrammarException")||msg.contains("SQLSyntaxErrorException")){
            msg = "数据库脚本异常";
            code = E0001.getStatus();
        }
        RequestResult requestResult =
                new RequestResult(false,null,msg,code);
        return requestResult;
    }

    /**
     * 校验的异常处理
     */
    @ExceptionHandler({BindException.class})
    public RequestResult validException1(BindException e) {
        RequestResult requestResult =
                new RequestResult(false,null,
                        e.getAllErrors().get(0).getDefaultMessage(),JsonCommonCodeEnum.E0002.getStatus());
        return requestResult;
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    public RequestResult validException2(MethodArgumentNotValidException e) {
        RequestResult requestResult =
                new RequestResult(false,null,
                        e.getBindingResult().getAllErrors().get(0).getDefaultMessage(),
                        JsonCommonCodeEnum.E0002.getStatus());
        return requestResult;
    }

    public HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
}
